

import java.awt.Point;
import java.awt.geom.Point2D;
import java.awt.geom.Point2D.Double;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Vector;

public class Taxi {

	private static int place = 2;
	private static int pas = 1;
	private static int haha=5;
	private int occupiedPlaces;
	private Point2D.Double currentPositionTaxi;
	private Point2D.Double precedentPositionTaxi;
	private Vector<Point2D.Double> itinerary;
	private ArrayList<Client> takenClientList;//Clients who are in this taxi
	private ArrayList<Client> waitingClientList;//Clients that the taxi want to pick up
	
	private Vector<Point2D.Double> traceTaxi;
	
	//int status;//0: empty, 1: 1 client, 2: 2 clients (full)
	
	public Taxi(int occupiedPlaces,Point2D.Double currentPositionTaxi,Vector<Point2D.Double> itinerary){
		this.occupiedPlaces = occupiedPlaces;
		this.itinerary = itinerary;
		this.currentPositionTaxi=currentPositionTaxi;
		this.precedentPositionTaxi =(Double) currentPositionTaxi.clone();
		this.takenClientList = new ArrayList<Client>();
		this.waitingClientList = new ArrayList<Client>();
		this.traceTaxi = new Vector<Point2D.Double>();
		
	}

	public void calculItinerary(){
//		- distance taxi -> client pos
//		- distance client pos -> client dest
//		- temps attente client
	// taxi vide
		for (Client c : Motor.clients){
			for (Client c1 : Motor.clients){
				if (!c1.equals(c)){
					Vector<Itinerary> itineraries = Itinerary.graphePossibilities(c, c1);
					bestPath(itineraries);	
				}
			}
			
		}
		
	// taxi avec un client 
	//	si client en cours de route qui respecte cercle d'acceptation + destination OK, le prendre
	//taxi plein - pas d'acction
		
	}
	
	
	private Vector<Itinerary> bestPath(Vector<Itinerary> itineraries) {
		//
		if(this.takenClientList.size()==2)
			return null;

		
		if(this.takenClientList.size()==1)
			return null;
	
		//First itinerary
		Itinerary it = itineraries.get(0);
		
		
	
	
		return null;
		
	}

	public void Move()
	{
		while(this.itinerary.size()!=0)
		{
			
			
				System.out.print("-----------------------------------------------------------------------------------------------------------------------------------------------\n");
				System.out.println("Before moving 1 pas,the positon : "+this.currentPositionTaxi+" to "+this.itinerary.firstElement());
				this.Out();
		
				Point2D.Double tempPosition = itinerary.firstElement();
				
				double z = currentPositionTaxi.distance(tempPosition);
				
				System.out.println("Distance from current position to next cible position "+tempPosition+" : "+z);
				
				Client tempClient = this.getClientByPosition(tempPosition);
				double fx;
				double fy;
				
				fx = Math.abs(currentPositionTaxi.x - tempPosition.getX() );
				fy = Math.abs(currentPositionTaxi.y - tempPosition.getY() );
				
				double fxx;
				double fyy;
				
				fxx = pas/z*fx;
				fyy = pas/z*fy;
		
				this.traceTaxi.addElement(precedentPositionTaxi);
				this.precedentPositionTaxi = (Double) this.currentPositionTaxi.clone();
				
				if(currentPositionTaxi.x < tempPosition.getX() && currentPositionTaxi.y < tempPosition.getY() )//1
				{
					
					currentPositionTaxi.x +=fxx;
					currentPositionTaxi.y +=fyy;
					
					if(currentPositionTaxi.x >= tempPosition.getX() && currentPositionTaxi.y >= tempPosition.getY())
					{
						itinerary.remove(0);
						this.waitingClientList.remove(tempClient);
						
						if(occupiedPlaces <place){
							tempClient.setStatus(1);
							this.takenClientList.add(tempClient);
							this.occupiedPlaces++;
						}
						else
						{
							System.out.println("\t Erreur: This taxi doesnt have enough place available ");
						}
						
					}
					
				}
				else if(currentPositionTaxi.x > tempPosition.getX() && currentPositionTaxi.y < tempPosition.getY())//2
				{
					currentPositionTaxi.x -=fxx;
					currentPositionTaxi.y +=fyy;
					
					if(currentPositionTaxi.x <= tempPosition.getX() && currentPositionTaxi.y >= tempPosition.getY())
					{
						itinerary.remove(0);
						this.waitingClientList.remove(tempClient);
						
						if(occupiedPlaces <place){
							
							tempClient.setStatus(1);
							this.takenClientList.add(tempClient);
							this.occupiedPlaces++;
						}
					}
				}
				else if(currentPositionTaxi.x > tempPosition.getX() && currentPositionTaxi.y > tempPosition.getY() )//3
				{
					currentPositionTaxi.x -=fxx;
					currentPositionTaxi.y -=fyy;
					
					if(currentPositionTaxi.x <= tempPosition.getX() && currentPositionTaxi.y <= tempPosition.getY() )
					{
						itinerary.remove(0);
						this.waitingClientList.remove(tempClient);
						
						if(occupiedPlaces<place)
						{
							tempClient.setStatus(1);
							this.takenClientList.add(tempClient);
							this.occupiedPlaces++;
						}
					}
				}
				else if(currentPositionTaxi.x < tempPosition.getX() && currentPositionTaxi.y > tempPosition.getY() )//4
				{
					currentPositionTaxi.x +=fxx;
					currentPositionTaxi.y -=fyy;
					
					if(currentPositionTaxi.x >= tempPosition.getX() && currentPositionTaxi.y <= tempPosition.getY() )
					{
						itinerary.remove(0);
						this.waitingClientList.remove(tempClient);
						
						if(occupiedPlaces <place)
						{
							tempClient.setStatus(1);
							this.takenClientList.add(tempClient);
							this.occupiedPlaces++;
						}
					}
				}
				
				System.out.println("After moving 1 pas,the positon : "+this.currentPositionTaxi);
				
				//this.DropClient(currentPositionTaxi);
		}
		
	}
	
	public Vector<Point2D.Double> getTraceTaxi() {
		return traceTaxi;
	}

	public void setTraceTaxi(Vector<Point2D.Double> traceTaxi) {
		this.traceTaxi = traceTaxi;
	}

	public Point2D.Double getCurrentPositionTaxi() {
		return currentPositionTaxi;
	}

	public void setCurrentPositionTaxi(Point2D.Double currentPositionTaxi) {
		this.currentPositionTaxi = currentPositionTaxi;
	}

	public Point2D.Double getPrecedentPositionTaxi() {
		return precedentPositionTaxi;
	}

	public void setPrecedentPositionTaxi(Point2D.Double precedentPositionTaxi) {
		this.precedentPositionTaxi = precedentPositionTaxi;
	}

	public int getOccupiedPlaces() {
		return occupiedPlaces;
	}

	public void setOccupiedPlaces(int occupiedPlaces) {
		// +1 quand un client arrive
		// Si occupiedPlace == 2, setstatus = 2
		this.occupiedPlaces = occupiedPlaces;
	}

	
	public Point2D.Double getPosition() {
		return currentPositionTaxi;
	}

	public void setPosition(Point2D.Double currentPositionTaxi) {
		this.currentPositionTaxi = currentPositionTaxi;
	}

	public Vector<Point2D.Double> getItinerary() {
		return itinerary;
	}

	public void setItinerary(Vector<Point2D.Double> itinerary) {
		//en fonction clients dans le taxi + client en attente sur son chemin qu'il pourrait prendre
		this.itinerary = itinerary;
	}

	
	public ArrayList<Client> getTekenClientList() {
		return takenClientList;
	}

	public void setTekenClientList(ArrayList<Client> tekenClientList) {
		this.takenClientList = tekenClientList;
	}

	public ArrayList<Client> getWaitingClientList() {
		return waitingClientList;
	}

	public void setWaitingClientList(ArrayList<Client> waitingClientList) {
		this.waitingClientList = waitingClientList;
	}

	public Client getClientByPosition(Point2D.Double position)
	{
		Client client=null;
		for(int i=0;i<this.waitingClientList.size();i++)
		{
			if(this.waitingClientList.get(i).getPosition().equals(position))
			{
				client =this.waitingClientList.get(i);
			}
		}
		return client;
	}
	
	public void Out ()
	{
		System.out.println("\t this.occupiedPlaces :"+this.occupiedPlaces);
		System.out.println("\t waitingClientList.size() : "+this.waitingClientList.size());
		System.out.println("\t tekenClientList.size() : "+this.takenClientList.size());
		System.out.println("\t precedentPositionTaxi : "+this.precedentPositionTaxi);
		System.out.println("\t currentPositionTaxi : "+this.currentPositionTaxi);

		
		
			for(int i=0;i<this.takenClientList.size();i++)
		{
				System.out.println("\t\t Client "+(i+1)+" status : "+this.takenClientList.get(i).getStatus());
		}
	}
	
	public void DropClient(Point2D.Double desti)
	{
		Iterator<Client> it = this.takenClientList.iterator();
		ArrayList<Client> clientList = new ArrayList<Client>();

		while(it.hasNext())
		{
			Client client = it.next();
			if(client.getPosition().equals(desti))
			{
				clientList.add(client);
			}		
		}
		
		if(this.takenClientList.removeAll(clientList))
		{
			for(int i=0;i<clientList.size();i++)
			{
				this.occupiedPlaces--;
			}
		}

	}
	
	public void DropClient(Client client)
	{
		
		if(this.takenClientList.remove(client))
		{
			
				this.occupiedPlaces--;
			
		}

	}

	public static void main(String [] args){
		
		Point2D.Double currentPositionTaxi = new Point2D.Double (0.0,0.0);
		
		Point2D.Double positionClient1 = new Point2D.Double (2.0,2.0);
		Point2D.Double positionClient2 = new Point2D.Double (4.0,4.0);
		Point2D.Double positionClient3 = new Point2D.Double (8.0,8.0);
		Point2D.Double positionClient4 = new Point2D.Double (16.0,16.0);
		
		Vector<Point2D.Double> itinerary =new Vector<Point2D.Double>();
		itinerary.add(positionClient1);
		itinerary.add(positionClient2);
		itinerary.add(positionClient3);
		itinerary.add(positionClient4);
		
		Client client1 = new Client(positionClient1);
		Client client2 = new Client(positionClient2);
		Client client3 = new Client(positionClient3);
		Client client4 = new Client(positionClient4);
		
		ArrayList<Client> waitingClientList = new ArrayList<Client> ();
		waitingClientList.add(client1);
		waitingClientList.add(client2);
		waitingClientList.add(client3);
		waitingClientList.add(client4);
		
		Taxi taxi = new Taxi(0,currentPositionTaxi,itinerary);
		
		taxi.setWaitingClientList(waitingClientList);
		taxi.Move();
		taxi.DropClient(new Point2D.Double (4.0,4.0));

		
		
	}
}
